/*******************************************************************************
 * Package: com.song.common.util
 * Type:    JsonUtils
 * Date:    2023-04-08 21:20
 *
 * Copyright (c) 2023 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.song.common.util;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 功能描述：
 *
 * @author Songxianyang
 * @date 2023-04-08 21:20
 */
@Slf4j
public class JsonUtils {
    private static ObjectMapper mapper = new ObjectMapper();

    private JsonUtils() {
    }

    public static String toJson(Object value) {
        if (value instanceof String) {
            return (String)value;
        } else {
            try {
                return mapper.writeValueAsString(value);
            } catch (JsonProcessingException var2) {
                throw new RuntimeException(var2);
            }
        }
    }

    public static <T> T toObject(String json, Class<T> type, Class<?>... innerClasses) {
        JavaType javaType = parseJavaType(type, innerClasses);

        try {
            return mapper.readValue(json, javaType);
        } catch (JsonProcessingException var2) {
            throw new RuntimeException(var2);
        }
    }

    public static <T> T toObject(InputStream inputStream, Class<T> type, Class<?>... innerClasses) {
        JavaType javaType = parseJavaType(type, innerClasses);

        try {
            return mapper.readValue(inputStream, javaType);
        } catch (IOException var2) {
            throw new RuntimeException(var2);
        }
    }

    public static List<?> toObjectList(String json, Class<?> type, Class<?>... innerClasses) {
        JavaType javaType = parseJavaType(type, innerClasses);

        try {
            return (List)mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(ArrayList.class, javaType));
        } catch (JsonProcessingException var2) {
            throw new RuntimeException(var2);
        }
    }
    private static JavaType parseJavaType(Class<?> type, Class<?>... innerClasses) {
        TypeFactory typeFactory = mapper.getTypeFactory();
        if (innerClasses != null && innerClasses.length != 0) {
            if (innerClasses.length == 1) {
                return typeFactory.constructParametricType(type, innerClasses);
            } else {
                JavaType innerType = typeFactory.constructParametricType(innerClasses[0], (Class[]) ArrayUtils.subarray(innerClasses, 1, innerClasses.length));
                return typeFactory.constructParametricType(type, new JavaType[]{innerType});
            }
        } else {
            return typeFactory.constructType(type);
        }
    }

    public static String getText(String json, String fieldName) {
        JsonNode root;
        try {
            root = mapper.readTree(json);
        } catch (JsonProcessingException var2) {
            throw new RuntimeException(var2);
        }

        JsonNode node = root.get(fieldName);
        return node != null ? node.asText() : null;
    }

    public static Integer getInt(String json, String fieldName) {
        JsonNode root;
        try {
            root = mapper.readTree(json);
        } catch (JsonProcessingException var2) {
            throw new RuntimeException(var2);
        }

        JsonNode node = root.get(fieldName);
        return node != null ? node.asInt() : null;
    }

    public static Long getLong(String json, String fieldName) {
        JsonNode root;
        try {
            root = mapper.readTree(json);
        } catch (JsonProcessingException var4) {
            throw new RuntimeException(var4);
        }

        JsonNode node = root.get(fieldName);
        return node != null ? node.asLong() : null;
    }

    public static Boolean getBoolean(String json, String fieldName) {
        JsonNode root;
        try {
            root = mapper.readTree(json);
        } catch (JsonProcessingException var4) {
            throw new RuntimeException(var4);
        }

        JsonNode node = root.get(fieldName);
        return node != null ? node.asBoolean() : null;
    }

    public static Double getDouble(String json, String fieldName) {
        JsonNode root;
        try {
            root = mapper.readTree(json);
        } catch (JsonProcessingException var4) {
            throw new RuntimeException(var4);
        }

        JsonNode node = root.get(fieldName);
        return node != null ? node.asDouble() : null;
    }


    public static boolean isValidJson(Object object) {
        String jsonStr;
        if (object instanceof String) {
            jsonStr = (String)object;
        } else {
            try {
                jsonStr = mapper.writeValueAsString(object);
            } catch (JsonProcessingException var4) {
                return false;
            }
        }

        try {
            mapper.readValue(jsonStr, Map.class);
            return true;
        } catch (JsonProcessingException var3) {
            return false;
        }
    }

    public static <T> T toObject(String text, Class<T> clazz) {
        if (StrUtil.isEmpty(text)) {
            return null;
        }
        try {
            return mapper.readValue(text, clazz);
        }
        catch (IOException e) {
            log.error("json parse err,json:{}", text, e);
            throw new RuntimeException(e);
        }
    }
}
